use crate::state::{Action, Event, State, Task};
use chrono::NaiveDate;
use yew::prelude::*;
use yew_store::StoreLink;

pub struct Model {
    store: StoreLink<State, Action>,
    on_item_click: Callback<i32>,
    link: ComponentLink<Self>,
}

#[derive(Properties)]
pub struct Props {
    #[props(required)]
    pub store: StoreLink<State, Action>,
    #[props(required)]
    pub on_item_click: Callback<i32>,
    // #[props(required)]
    // pub ondecrement: Callback<isize>,
}

pub enum Msg {
    StoreEvent(Event),
    ShowComent(i32),
}

impl Component for Model {
    type Message = Msg;
    type Properties = Props;

    fn create(props: Self::Properties, mut link: ComponentLink<Self>) -> Self {
        let callback = link.send_back(|event| Msg::StoreEvent(event));
        Model {
            store: props.store.reform(Some(callback)),
            link,
            on_item_click: props.on_item_click,
        }
    }

    fn update(&mut self, msg: Self::Message) -> ShouldRender {
        match msg {
            Msg::StoreEvent(_) => (),
            Msg::ShowComent(tid) => {
                self.on_item_click.emit(tid);
                self.store.send(Action::SetSelectedTask(Some(tid)));
                return false;
            }
        }
        true
    }

    fn change(&mut self, props: Self::Properties) -> ShouldRender {
        let callback = self.link.send_back(|event| Msg::StoreEvent(event));
        self.store = props.store.reform(Some(callback));
        self.on_item_click = props.on_item_click;
        true
    }
}

impl Renderable<Model> for Model {
    fn view(&self) -> Html<Self> {
        let state = self.store.state();
        html! {
            <div>
                {for state.tasks.iter().rev().map(|(date, daliy_tasks)| self.daliy_task_view(date, daliy_tasks))}
            </div>
        }
    }
}

impl Model {
    fn daliy_task_view(&self, date: &NaiveDate, tasks: &Vec<Task>) -> Html<Self> {
        html! {
            <ul>
                <li class="flex justify-start my-2"><span class="text-gray-400 text-xs">{date.format("%Y年%m月%d日").to_string()}</span></li>
                {for tasks.iter().map(|task| self.task_view(task))}
            </ul>
        }
    }

    fn task_view(&self, task: &Task) -> Html<Self> {
        let cid = task.id;
        let mut item_classes = vec!["text-lg", "truncate"];
        self.store
            .state()
            .selected_task_id
            .filter(|&tid| tid == cid)
            .map(|_| item_classes.push("text-blue-600"));
        html! {
            <li>
                <p class=item_classes onclick=|_| Msg::ShowComent(cid)>{task.description.as_str()}</p>
            </li>
        }
    }
}
